// ============================== 导入依赖 ============================== //

import dayjs from 'dayjs'
import axios from 'axios'
import IS from './is'

const trans = (path) => path.replace(/^\//, '')

// ============================== 导出文件工具 ============================== //

export default {
  /**
   * 文件地址
   *
   * @param {String} path  相对地址
   * @param {String} empty 空白文件
   *
   * @returns {String} 完整地址
   */
  file(path, empty) {
    const { PREFIX, SUFFIX, EMPTY } = this.FILE || {}
    if (!path || !IS.isString(path)) return empty === undefined ? EMPTY : empty
    if (/^http(s?):\/\//.test(path)) return `${path}?${this.VERSION}`

    const prefix = PREFIX.replace(/\/$/, '')
    const url = trans(path).replace(prefix.slice(1), '')
    return `${prefix}/${url}${SUFFIX}?${this.VERSION}`
  },

  /**
   * CDN 地址
   *
   * @param {String} path  相对 /cdn/ 之后的地址，开头可加 / 也可不加 /
   * @returns {String} 完整地址
   */
  cdn(path) {
    return `${process.env.VUE_APP_CDN}/${trans(path)}?${this.VERSION}`
  },

  /**
   * 公共地址
   *
   * @param {String} path  相对 /common/ 之后的地址，开头可加 / 也可不加 /
   * @returns {String} 完整地址
   */
  common(path) {
    return `${process.env.VUE_APP_COMMON}/${trans(path)}?${this.VERSION}`
  },

  /**
   * 资源地址
   *
   * @param {String} path  相对 /asset/ 之后的地址，开头可加 / 也可不加 /
   * @returns {String} 完整地址
   */
  asset(path) {
    return `${process.env.VUE_APP_ASSET}/${trans(path)}?${this.VERSION}`
  },

  /**
   * 文件名称
   *
   * @param {File} file 文件 (为空则不带后缀)
   * @param {*} time 时间 (可由 dayjs 转换的数据，为空则取当前时间)
   *
   * @returns {String} 时间戳+随机数的文件名
   */
  fileName(file = {}, time) {
    const dayObj = time ? dayjs(time) : dayjs() // dayjs 对象
    const timeStr = dayObj.format('YYYY-MM-DD_HH.mm.ss.SSS') // 只含路径上能显示的字符
    const random = `${Math.random()}`.slice(-4) // 4 位随机数
    const suffix = (/(\.\w+)$/.exec(file.name) || [])[1] || '' // 后缀
    return `${timeStr}_${random}${suffix}`
  },

  /**
   * 文件上传
   *
   * @param {File} file 文件
   * @param {String} folder 目录
   * @param {String} business 业务
   *
   * @returns {String} 文件路径
   */
  async fileUpload(file, folder = 'file', business = 'public') {
    const { PREFIX, SUFFIX } = this.FILE || {}
    const prefix = `${PREFIX.replace(/(^\/)|(\/$)/g, '')}/${folder.replace(/(^\/)|(\/$)/g, '')}`

    this.loading()
    return new Promise((resolve) => {
      const subUrl = `${prefix}/${this.fileName(file)}${SUFFIX}?${this.VERSION}`
      setTimeout(() => {
        resolve(subUrl)
        this.unloading()
      }, 300)
    })
  },

  /**
   * 文件下载
   *
   * @param {String} path  相对地址
   * @param {String} name  文件名称
   */
  async fileDownload(path = '', name = '') {
    if (IS.isEmpty(path)) return

    const url = this.file(path)
    const matched = /\/([^/?]+)(\?.*)?$/.exec(path)
    const downName = name || (matched ? matched[1] : this.fileName())

    this.loading()
    axios.get(url, { responseType: 'blob' })
      .then(({ data }) => {
        this.fileSave(data, downName)
        this.unloading()
      }).catch(e => {
        this.logError('文件下载', { path, name: downName }, e)
        this.unloading()
      })
  },

  /**
   * 文件获取 base64 编码串
   *
   * @param {File} file 文件对象
   *
   * @returns {String} base64
   */
  fileBase64(file) {
    if (IS.isEmpty(file)) return ''

    this.loading()
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = () => {
        resolve(reader.result)
        this.unloading()
      }
      reader.onerror = (error) => {
        reject(error)
        this.unloading()
      }
    })
  },

  /**
   * 文件获取二进制编码串
   *
   * @param {File} file 文件对象
   *
   * @returns {String} bytes
   */
  fileBytes(file) {
    if (IS.isEmpty(file)) return ''
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.readAsBinaryString(file)
      reader.onload = () => resolve(btoa(reader.result))
      reader.onerror = (error) => reject(error)
    })
  },

  /**
   * 文件保存
   *
   * @param {String} binary 二进制流
   * @param {String} name  文件名称
   */
  fileSave(binary, name) {
    // 创建对象路径
    const blob = new Blob([binary])
    // 创建下载链接
    const url = window.URL.createObjectURL(blob)

    // 创建 <a> 标签
    const link = document.createElement('a')

    // 设置属性
    link.href = url
    link.download = decodeURI(/\.[a-zA-Z][a-zA-Z0-9]*$/.test(name) ? name : `${name}.xlsx`)
    link.target = '_blank'
    link.style.display = 'none'

    // 点击下载
    link.click()

    // 释放掉blob对象
    window.URL.revokeObjectURL(url)
  },
}
